package com.sihai.core.support;

import com.sihai.core.Sorter;
import org.apache.commons.lang.NotImplementedException;
import org.hibernate.*;
import org.hibernate.jdbc.Work;
import org.hibernate.stat.SessionStatistics;

import java.io.Serializable;
import java.sql.Connection;

public class EnhancedSession implements Session {

	private static final long serialVersionUID = 6125309116797030144L;

	protected Session session;

	private Sorter sorter;

	public EnhancedSession(Session session, Sorter sorter) {
		this.session = session;
		this.sorter = sorter;
	}

	public EntityMode getEntityMode() {
		return session.getEntityMode();
	}

	public Session getSession(EntityMode entityMode) {
		return session.getSession(entityMode);
	}

	public void flush() throws HibernateException {
		session.flush();
	}

	public void setFlushMode(FlushMode flushMode) {
		session.setFlushMode(flushMode);
	}

	public FlushMode getFlushMode() {
		return session.getFlushMode();
	}

	public void setCacheMode(CacheMode cacheMode) {
		session.setCacheMode(cacheMode);
	}

	public CacheMode getCacheMode() {
		return session.getCacheMode();
	}

	public SessionFactory getSessionFactory() {
		return session.getSessionFactory();
	}

	@Deprecated
	public Connection connection() throws HibernateException {
		throw new NotImplementedException("deprecated method is not supported");
	}

	public Connection close() throws HibernateException {
		return session.close();
	}

	public void cancelQuery() throws HibernateException {
		session.cancelQuery();
	}

	public boolean isOpen() {
		return session.isOpen();
	}

	public boolean isConnected() {
		return session.isConnected();
	}

	public boolean isDirty() throws HibernateException {
		return session.isDirty();
	}

	public Serializable getIdentifier(Object object) throws HibernateException {
		return session.getIdentifier(object);
	}

	public boolean contains(Object object) {
		return session.contains(object);
	}

	public void evict(Object object) throws HibernateException {
		session.evict(object);
	}

	public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException {
		return session.load(theClass, id, lockMode);
	}

	public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
		return session.load(entityName, id, lockMode);
	}

	public Object load(Class theClass, Serializable id) throws HibernateException {
		return session.load(theClass, id);
	}

	public Object load(String entityName, Serializable id) throws HibernateException {
		return session.load(entityName, id);
	}

	public void load(Object object, Serializable id) throws HibernateException {
		session.load(object, id);
	}

	public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException {
		session.replicate(object, replicationMode);
	}

	public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException {
		session.replicate(entityName, object, replicationMode);
	}

	public Serializable save(Object object) throws HibernateException {
		return session.save(object);
	}

	public Serializable save(String entityName, Object object) throws HibernateException {
		return session.save(entityName, object);
	}

	public void saveOrUpdate(Object object) throws HibernateException {
		session.saveOrUpdate(object);
	}

	public void saveOrUpdate(String entityName, Object object) throws HibernateException {
		session.saveOrUpdate(entityName, object);
	}

	public void update(Object object) throws HibernateException {
		session.update(object);
	}

	public void update(String entityName, Object object) throws HibernateException {
		session.update(entityName, object);
	}

	public Object merge(Object object) throws HibernateException {
		return session.merge(object);
	}

	public Object merge(String entityName, Object object) throws HibernateException {
		return session.merge(entityName, object);
	}

	public void persist(Object object) throws HibernateException {
		session.persist(object);
	}

	public void persist(String entityName, Object object) throws HibernateException {
		session.persist(entityName, object);
	}

	public void delete(Object object) throws HibernateException {
		session.delete(object);
	}

	public void delete(String entityName, Object object) throws HibernateException {
		session.delete(entityName, object);
	}

	public void lock(Object object, LockMode lockMode) throws HibernateException {
		session.lock(object, lockMode);
	}

	public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException {
		session.lock(entityName, object, lockMode);
	}

	public void refresh(Object object) throws HibernateException {
		session.refresh(object);
	}

	public void refresh(Object object, LockMode lockMode) throws HibernateException {
		session.refresh(object, lockMode);
	}

	public LockMode getCurrentLockMode(Object object) throws HibernateException {
		return session.getCurrentLockMode(object);
	}

	public Transaction beginTransaction() throws HibernateException {
		return session.beginTransaction();
	}

	public Transaction getTransaction() {
		return session.getTransaction();
	}

	public Criteria createCriteria(Class persistentClass) {
		return session.createCriteria(persistentClass);
	}

	public Criteria createCriteria(Class persistentClass, String alias) {
		return session.createCriteria(persistentClass, alias);
	}

	public Criteria createCriteria(String entityName) {
		return session.createCriteria(entityName);
	}

	public Criteria createCriteria(String entityName, String alias) {
		return session.createCriteria(entityName, alias);
	}

	public Query createQuery(String queryString) throws HibernateException {
		return new CountableQuery(session, session.createQuery(sorter == null ? queryString
				: sorter.decorate(queryString)));
	}

	public SQLQuery createSQLQuery(String queryString) throws HibernateException {
		return session.createSQLQuery(sorter == null ? queryString : sorter.decorate(queryString));
	}

	public Query createFilter(Object collection, String queryString) throws HibernateException {
		return session.createFilter(collection, queryString);
	}

	public Query getNamedQuery(String queryName) throws HibernateException {
		return session.getNamedQuery(queryName);
	}

	public void clear() {
		session.clear();
	}

	public Object get(Class clazz, Serializable id) throws HibernateException {
		return session.get(clazz, id);
	}

	public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException {
		return session.get(clazz, id, lockMode);
	}

	public Object get(String entityName, Serializable id) throws HibernateException {
		return session.get(entityName, id);
	}

	public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
		return session.get(entityName, id, lockMode);
	}

	public String getEntityName(Object object) throws HibernateException {
		return session.getEntityName(object);
	}

	public Filter enableFilter(String filterName) {
		return session.enableFilter(filterName);
	}

	public Filter getEnabledFilter(String filterName) {
		return session.getEnabledFilter(filterName);
	}

	public void disableFilter(String filterName) {
		session.disableFilter(filterName);
	}

	public SessionStatistics getStatistics() {
		return session.getStatistics();
	}

	public void setReadOnly(Object entity, boolean readOnly) {
		session.setReadOnly(entity, readOnly);
	}

	public void doWork(Work work) throws HibernateException {
		session.doWork(work);
	}

	public Connection disconnect() throws HibernateException {
		return session.disconnect();
	}

	@Deprecated
	public void reconnect() throws HibernateException {
		throw new NotImplementedException("deprecated method is not supported");
	}

	public void reconnect(Connection connection) throws HibernateException {
		session.reconnect(connection);
	}

	public Session getNativeSession() {
		return session;
	}

	@Override
	public boolean isDefaultReadOnly() {
		return session.isDefaultReadOnly();
	}

	@Override
	public void setDefaultReadOnly(boolean readOnly) {
		this.session.setDefaultReadOnly(readOnly);
	}

	@Override
	public Object load(Class theClass, Serializable id, LockOptions lockOptions) throws HibernateException {
		return this.session.load(theClass, id, lockOptions);
	}

	@Override
	public Object load(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException {
		return this.session.load(entityName, id, lockOptions);
	}

	@Override
	public LockRequest buildLockRequest(LockOptions lockOptions) {
		return this.session.buildLockRequest(lockOptions);
	}

	@Override
	public void refresh(Object object, LockOptions lockOptions) throws HibernateException {
		this.session.refresh(object, lockOptions);
	}

	@Override
	public Object get(Class clazz, Serializable id, LockOptions lockOptions) throws HibernateException {
		return this.session.get(clazz, id, lockOptions);
	}

	@Override
	public Object get(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException {
		return this.session.get(entityName, id, lockOptions);
	}

	@Override
	public boolean isReadOnly(Object entityOrProxy) {
		return this.session.isReadOnly(entityOrProxy);
	}

	@Override
	public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
		return this.session.isFetchProfileEnabled(name);
	}

	@Override
	public void enableFetchProfile(String name) throws UnknownProfileException {
		this.session.enableFetchProfile(name);
	}

	@Override
	public void disableFetchProfile(String name) throws UnknownProfileException {
		this.session.disableFetchProfile(name);
	}
}
